package com.rivues.util.tools;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.bean.TaskInfo;
import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.module.platform.web.model.SystemCalendar;
import com.rivues.util.serialize.JSON;

public class TaskHelper {
	
	public enum TaskStopType{
		STOP_NOW ,
		STOP_AFTER_ALL_REQUEST ,
		STOP_PAUSE ,
		RESTART;
		
		public String toString(){
			return super.toString() ;
		}
	}
	/**
	 * 
	 * @param jobId
	 * @return
	 * @throws TaskException
	 */
	public static boolean stopTaskJob(String jobId , String stopType) throws TaskException {
		Map<String, Object> jobDetailMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.JOBDETAIL.toString());
		Map<String, Object> runningJobMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.RUNNINGJOB.toString());
		
		if(runningJobMap.get(jobId)!=null){
			JobDetail jobDetail = (JobDetail) runningJobMap.get(jobId) ;
			if(TaskHelper.TaskStopType.STOP_NOW.toString().equals(stopType)){
				if(runningJobMap.get(jobId)!=null){
					jobDetail.setFetcher(false) ;
				}
			}else if(TaskHelper.TaskStopType.STOP_AFTER_ALL_REQUEST.toString().equals(stopType)){
				if(runningJobMap.get(jobId)!=null){
					jobDetail.setFetcher(false) ;
				}
			}else if(TaskHelper.TaskStopType.STOP_PAUSE.toString().equals(stopType)){
				if(runningJobMap.get(jobId)!=null){
					jobDetail.setPause(true);
				}
			}
			else if(TaskHelper.TaskStopType.RESTART.toString().equals(stopType)){
				if(runningJobMap.get(jobId)!=null){
					jobDetail.setPause(false);
				}
			}
			runningJobMap.put(jobId, jobDetail) ;
		}else if(jobDetailMap.get(jobId)!=null){
			JobDetail jobDetail = (JobDetail) jobDetailMap.get(jobId) ;
			jobDetail.setFetcher(false) ;
			jobDetailMap.put(jobId, jobDetail) ;
		}else{
			JobDetail jobDetail = (JobDetail) RivuDataContext.getService().getIObjectByPK(JobDetail.class, jobId) ;
			if(StringUtil.isNotNull(jobDetail.getCronexp())){
				try {
					jobDetail.setNextfiretime(CronTools.getFinalFireTime(jobDetail.getCronexp(), jobDetail.getNextfiretime()!=null ? jobDetail.getNextfiretime():new Date())) ;
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
			RivuDataContext.getService().updateIObject(jobDetail);
		}
		return true ;
	}
	/**
	 * 任务不存在的时候会启动失败
	 * @param jobId
	 * @return
	 * @throws TaskException
	 */
	@SuppressWarnings("unchecked")
	public static boolean startTaskJob(String jobId , String startType) throws TaskException {
		try{
			JobDetail jobDetail = (JobDetail) RivuDataContext.getService().getIObjectByPK(JobDetail.class, jobId) ;
			jobDetail.setTaskstatus(RivuDataContext.TaskStatusType.READ.getType()) ;
			jobDetail.setNextfiretime(updateTaskNextFireTime(jobDetail)) ;
			RivuDataContext.getService().updateIObject(jobDetail) ;
		}catch(Exception ex){
			return false ;
		}
		return true ;
	}
	
	public static Date updateTaskNextFireTime(JobDetail jobDetail){
		Date nextFireDate = new Date();
		Date date = new Date();
		if(jobDetail!=null && jobDetail.getCronexp()!=null && jobDetail.getCronexp().length()>0){
			try {
				nextFireDate = (CronTools.getFinalFireTime(jobDetail.getCronexp(), jobDetail.getNextfiretime()!=null ? jobDetail.getNextfiretime() : date)) ;
				TaskInfo taskinfo = JSON.parseObject(jobDetail.getTaskinfo(), TaskInfo.class) ;
				if(taskinfo.getDatetypes()!=null&&taskinfo.getDatetypes().length>0){//如果选择了假日筛选，那么进行筛选
					DetachedCriteria criteria = DetachedCriteria.forClass(SystemCalendar.class).add(Restrictions.eq("orgi",jobDetail.getOrgi())).add(Restrictions.ge("dateflag",new SimpleDateFormat("yyyy-MM-dd").format(date))).addOrder(Order.asc("dateflag"));
					List<SystemCalendar> calendars = RivuDataContext.getService().findAllByCriteria(criteria);
					
					for (int i = 0; i < calendars.size(); i++) {
						String nextstring = new SimpleDateFormat("yyyy-MM-dd").format(nextFireDate);
						if(nextstring.startsWith(calendars.get(i).getDateflag())){
							
							//判断该日期是否在允许发送的日期类型内
							boolean innerflag = false;
							for (int j = 0; j < taskinfo.getDatetypes().length; j++) {
								if(calendars.get(i).getDatetype()==Integer.parseInt(taskinfo.getDatetypes()[j])){
									innerflag = true;
								}
							}
							if(!innerflag){//如果不在范围内，那么用刚生成的日期重新计算
								nextFireDate = (CronTools.getFinalFireTime(jobDetail.getCronexp(), nextFireDate)) ;
							}else{//在允许发送的范围内直接跳出
								break;
							}
						}
					}
					
					
				}
				
			} catch (ParseException e) {
				nextFireDate = new Date(System.currentTimeMillis() + 1000*60*60*24) ; 	//一旦任务的 Cron表达式错误，将下次执行时间自动设置为一天后，避免出现任务永远无法终止的情况
				e.printStackTrace();
			}
		}
		return nextFireDate ;
	}
	
	
	
	/**
	 * 
	 * @param jobId
	 * @return
	 * @throws TaskException
	 */
	public static boolean restartTaskJob(String jobId , String startType) throws TaskException {
		return true ;
	}
}
